/***************************************************************************
 *  Filename: computerwidget.cpp
 *  Class: ComputerWidget
 *
 *  Copyright 2012  Xander van Kooten
 *  <xandervk@gmail.com>
 *
 *  Copyright 2012  Mario Henrique Voorsluys
 *  <forcaeluz@gmail.com>
 *
 ****************************************************************************/

/*
 *
 * This file is part of Parsax-Remote-Controller.
 *
 *    Parsax-Remote-Controller is free software: you can redistribute it
 *    and/or modify it under the terms of the GNU General Public License
 *    as published by the Free Software Foundation, either version 3 of the
 *    License, or (at your option) any later version.
 *
 *    Parsax-Remote-Controller is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *    GNU General Public License for more details.
 *
 *    You should have received a copy of the GNU General Public License
 *    along with Parsax-Remote-Controller.
 *    If not, see <http://www.gnu.org/licenses/>.
 */

#include "computerwidget.h"
#include "ui_computerwidget.h"
#include <QInputDialog>
#include <QMenu>

ComputerWidget::ComputerWidget(RemoteComputer *comp, QWidget *parent) :
    QWidget(parent),
    ui(new Ui::ComputerWidget)
{
    if(comp==0){
        computer = new RemoteComputer(this);
    }
    ui->setupUi(this);
    whenDisconnected();
    model = new ProcessModel(false, this);
    ui->tableView->setModel(model);
    ui->tableView->horizontalHeader()->setResizeMode(1, QHeaderView::Stretch);
    connect(computer, SIGNAL(connectionEstablished()), SLOT(whenConnected()));
    connect(computer, SIGNAL(connectionLost()), SLOT(whenDisconnected()));
}

ComputerWidget::~ComputerWidget()
{
    delete ui;
}

void ComputerWidget::initialize(){
    whenDisconnected();
}

void ComputerWidget::whenConnected(){
    ui->nameEdit->setDisabled(true);
    ui->addressEdit->setDisabled(true);
    ui->portEdit->setDisabled(true);
    ui->connectButton->setText("Disconnect");
    foreach(ProcessGUI *prcs, processes){
        prcs->setStatus("nostatus");
    }
}

void ComputerWidget::whenDisconnected(){
    ui->nameEdit->setDisabled(false);
    ui->addressEdit->setDisabled(false);
    ui->portEdit->setDisabled(false);
    ui->connectButton->setText("Connect");
    foreach(ProcessGUI *prcs, processes){
        prcs->setStatus("disconnected");
    }
}

void ComputerWidget::setName(QString tname){
    computer->setName(tname);
    ui->nameEdit->setText(computer->getName());
}

void ComputerWidget::setAddress(QString taddress){
    computer->setAddress(taddress);
    ui->addressEdit->setText(computer->getAddress());
}

void ComputerWidget::setPort(int tport){
    computer->setPort(tport);
    ui->portEdit->setText(QString::number(computer->getPort()));
}

QString ComputerWidget::getName(){
    return computer->getName();
}

QString ComputerWidget::getAddress(){
    return computer->getAddress();
}

int ComputerWidget::getPort(){
    return computer->getPort();
}

QList<ProcessGUI*> ComputerWidget::getProcess(){
    return processes.values();
}

void ComputerWidget::addProccess(){
    computer->addProccess();
    ProcessGUI *tmpProcessUI = new ProcessGUI(0, this);
    ui->processesTabs->addTab(tmpProcessUI, "ProcessX");
}

void ComputerWidget::addProccess(ProcessGUI *newProc){
    model->addProcess(newProc->getProcess());
    computer->addProccess(newProc->getProcess());

    ui->tableView->resizeRowsToContents();
    processes.insert(newProc->getId(), newProc);

    newProc->setPc(getName());
    ui->processesTabs->addTab(newProc, newProc->getId());
    connect(newProc->getProcess(), SIGNAL(infoUpdated()), SLOT(updateButtonStates()));
}

void ComputerWidget::on_connectButton_clicked()
{
    if(computer->isConnected()){
        computer->disconnectFromSlave();
    }else{
        computer->connectToSlave();
    }
}

void ComputerWidget::on_startPrcsButton_clicked()
{
    QItemSelectionModel *selectionModel = ui->tableView->selectionModel();
    QModelIndexList indexes = selectionModel->selectedIndexes();
    if(indexes.size()==0){
        return;
    }
    RemoteProcess *tmpPrcs = (RemoteProcess*)model->data(indexes.at(0), 33).value<void*>();
    tmpPrcs->startProcess();
}

void ComputerWidget::whenStatusUpdateReceived(QString id, QString status){
    ProcessGUI *tmpPrcs = processes.value(id);
    tmpPrcs->setStatus(status);
    updateButtonStates();
}

void ComputerWidget::whenCLOReceived(QString id, int type, QString message){
    qDebug() << "[ComputerWidget] CLO Received";
    ProcessGUI *tmpPrcs = processes.value(id);
    if(type==0){
        tmpPrcs->appendClo(message);
    }else{
        tmpPrcs->appendClE(message);
    }
}

void ComputerWidget::on_stopPrcsButton_clicked()
{
    QItemSelectionModel *selectionModel = ui->tableView->selectionModel();
    QModelIndexList indexes = selectionModel->selectedIndexes();
    if(indexes.size()==0){
        return;
    }
    RemoteProcess *tmpPrcs = (RemoteProcess*)model->data(indexes.at(0), 33).value<void*>();
    tmpPrcs->stopProcess();
}


//void ComputerWidget::on_tableView_clicked(const QModelIndex &index)
//{
//    qDebug() << "[ComputerWidget] Table Clicked";
//    if(!index.isValid()){
//        ui->tableView->selectionModel()->clearSelection();
//        return;
//    }
//    updateButtonStates();
//}

void ComputerWidget::on_newPrcsButton_clicked()
{
    QString newId = QInputDialog::getText(this, "New Program", "Program ID (cannot be changed):");
    if(newId==""){
        return;
    }
    ProcessGUI *newPrcs = new ProcessGUI(0, this);
    newPrcs->setId(newId);
    newPrcs->setPc(this->name);
    addProccess(newPrcs);
    ui->processesTabs->setCurrentWidget(newPrcs);
    newPrcs->setProgram("");
    emit processAdded(newPrcs);

}

void ComputerWidget::on_nameEdit_textChanged(const QString &arg1)
{
    computer->setName(arg1);
    emit nameChanged(this, arg1);
}

void ComputerWidget::on_removeButton_clicked()
{
    QItemSelectionModel *selectionModel = ui->tableView->selectionModel();
    QModelIndexList indexes = selectionModel->selectedIndexes();
    if(indexes.size()==0){
        return;
    }
    RemoteProcess *tmpPrcs = (RemoteProcess*)model->data(indexes.at(0), 33).value<void*>();
    if(tmpPrcs==0){
        qDebug() << "[ComputerWidget] Something went wrong when parsing pointers";
        return;
    }
    foreach(ProcessGUI *tmp, processes){
        if(tmp->getProcess()==tmpPrcs){
            emit processRemoved(tmp);
            model->removeProcess(tmpPrcs);
            int index = ui->processesTabs->indexOf(tmp);
            ui->processesTabs->removeTab(index);
            processes.remove(tmp->getId());
            tmp->deleteLater();
            tmpPrcs->deleteLater();
        }
    }
}

void ComputerWidget::updateButtonStates(){
    QItemSelectionModel *selectionModel = ui->tableView->selectionModel();
    QModelIndexList indexes = selectionModel->selectedIndexes();
    if(indexes.size()==0){
        return;
    }
    RemoteProcess *tmpPrcs = (RemoteProcess*)model->data(indexes.at(0), 33).value<void*>();
    if(tmpPrcs==0){
        qDebug() << "[ComputerWidget] Something went wrong when parsing pointers";
        return;
    }

    QString tmpStatus = tmpPrcs->getStatus();
    qDebug() << "[ComputerWidget] Status from selected row is: " << tmpStatus;
    if(tmpStatus=="disconnected"){
        ui->startPrcsButton->setEnabled(false);
        ui->stopPrcsButton->setEnabled(false);
        ui->removeButton->setEnabled(false);
    }else if(tmpStatus=="starting"){
        ui->startPrcsButton->setEnabled(false);
        ui->stopPrcsButton->setEnabled(false);
        ui->removeButton->setEnabled(false);
    }else if(tmpStatus=="running"){
        ui->startPrcsButton->setEnabled(false);
        ui->stopPrcsButton->setEnabled(true);
        ui->removeButton->setEnabled(false);
    }else if(tmpStatus=="notrunning"){
        ui->startPrcsButton->setEnabled(true);
        ui->stopPrcsButton->setEnabled(false);
        ui->removeButton->setEnabled(true);
    }else if(tmpStatus=="nostatus"){
        ui->startPrcsButton->setEnabled(true);
        ui->stopPrcsButton->setEnabled(true);
        ui->removeButton->setEnabled(false);
    }else{
        ui->startPrcsButton->setEnabled(false);
        ui->stopPrcsButton->setEnabled(false);
        ui->removeButton->setEnabled(false);
    }
}

void ComputerWidget::on_addressEdit_textChanged(const QString &arg1)
{
    computer->setAddress(arg1);
}

void ComputerWidget::closeConnection(){
    computer->disconnectFromSlave();
}

void ComputerWidget::on_tableView_customContextMenuRequested(const QPoint &pos)
{
    qDebug() << "About to show menu";
}

RemoteComputer* ComputerWidget::getComputer(){
    return computer;
}
